package com.rc.net;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.rc.activity.dao.tbl_User;
import com.rc.db.DatabaseSupport;
import com.rc.object.BaseObject;
import com.rc.util.Const;
import com.rc.util.Util;

@SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class uploadfile {
	private Activity ct;
	private Bitmap photo;
	private Uri uri;

	public uploadfile(Activity ct, Bitmap photo) {
		super();
		this.ct = ct;
		this.photo = photo;
	}

	public uploadfile(Activity ct, Uri uri) {
		super();
		this.ct = ct;
	}

	TextView messageText;
	Button uploadButton;
	int serverResponseCode = 0;
	ProgressDialog dialog = null;
	String JsonContent = "";
	InputStream in = null;

	HttpURLConnection conn = null;
	DataOutputStream dos = null;
	String lineEnd = "\r\n";
	String twoHyphens = "--";
	String boundary = "*****";
	/********** File Path *************/
	final String uploadFilePath = "/mnt/sdcard";
	Vector<BaseObject> list;

	/**
	 * Upload file with uri of image.
	 * 
	 * @param uri
	 *            uri of image .
	 */
	@SuppressWarnings("resource")
	public String uploadFileWithUri(Uri uri) {
		if (android.os.Build.VERSION.SDK_INT > 9) {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}

		int bytesRead, bytesAvailable, bufferSize;
		byte[] buffer;
		int maxBufferSize = 1 * 1024 * 1024;

		try {

			// open a URL connection to the Servlet
			String filePath = getFilePathFromContentUri(uri,
					ct.getContentResolver());
			File file = null;
			InputStream is = null;
			if (filePath == null) {
				filePath = getImagePath(uri, ct);
			}
			file = new File(filePath);
			if (file != null) {
				UploadFileAmazon upload = new UploadFileAmazon();
				String filename = Util.validateNameImage(ct);
				if (upload.uploadfile(file, filename) != null) {
					ArrayList<BaseObject> arrBaseObjects = new ArrayList<BaseObject>();
					arrBaseObjects = NetSupport.ocrRequest(filename, ct);
					if (arrBaseObjects != null) {
						if (arrBaseObjects.size() > 0) {
							return "success";
						}
					}
				}
			}
			is = new FileInputStream(filePath);
			if (is == null) {
				return "fail";
			}
			// TODO : input file
			String upLoadServerUri = "https://testing.receiptclub.com/api/v2/receipt-images";
			URL url = new URL(upLoadServerUri);

			// Open a HTTP connection to the URL
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true); // Allow Inputs
			conn.setDoOutput(true); // Allow Outputs
			conn.setUseCaches(false); // Don't use a Cached Copy
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("ENCTYPE", "multipart/form-data");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);
			conn.setRequestProperty("Filedata", filePath);
			if ("".equals(Const.AUTHENKEY)) {
				tbl_User objUser = new tbl_User();
				objUser = DatabaseSupport.getTbl_User(ct);
				Const.AUTHENKEY = objUser.getToken();
			}
			conn.setRequestProperty("AUTH_TOKEN", Const.AUTHENKEY);

			dos = new DataOutputStream(conn.getOutputStream());

			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\"Filedata\";filename=\""
					+ filePath + "\"" + lineEnd);

			dos.writeBytes(lineEnd);

			// create a buffer of maximum size
			bytesAvailable = is.available();

			bufferSize = Math.min(bytesAvailable, maxBufferSize);
			buffer = new byte[bufferSize];

			// read file and write it into form...
			bytesRead = is.read(buffer, 0, bufferSize);

			while (bytesRead > 0) {

				dos.write(buffer, 0, bufferSize);
				bytesAvailable = is.available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = is.read(buffer, 0, bufferSize);

			}

			// send multipart form data necesssary after file data...
			dos.writeBytes(lineEnd);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

			// Responses from the server (code and message)
			serverResponseCode = conn.getResponseCode();
			String serverResponseMessage = conn.getResponseMessage();

			Log.i("uploadFile", "HTTP Response is : " + serverResponseMessage
					+ ": " + serverResponseCode);

			if (serverResponseCode == 200) {

				try {
					in = conn.getInputStream();
					JsonContent = readData(in);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				;
			} else {
				Toast.makeText(
						ct,
						"Currently, this android version is not supported Uploading function!",
						Toast.LENGTH_SHORT).show();
			}

			// close the streams //
			is.close();
			dos.flush();
			dos.close();

		} catch (MalformedURLException ex) {

			ex.printStackTrace();

			ct.runOnUiThread(new Runnable() {
				public void run() {

					Toast.makeText(ct, "MalformedURLException",
							Toast.LENGTH_SHORT).show();
				}
			});

			Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
		} catch (Exception e) {

			e.printStackTrace();

			Log.e("Upload file to server Exception",
					"Exception : " + e.getMessage(), e);
		}

		return JsonContent;
	}

	public InputStream openPath(Uri uri) {
		InputStream is = null;
		try {
			is = ct.getContentResolver().openInputStream(uri);
			// Convert your stream to data here
			is.close();
			return is;

		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public String getImagePath(Uri uri, Context ct) {
		Cursor cursor = ct.getContentResolver().query(uri, null, null, null,
				null);
		cursor.moveToFirst();
		String document_id = cursor.getString(0);
		document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
		cursor.close();

		cursor = ct.getContentResolver().query(
				android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				null, MediaStore.Images.Media._ID + " = ? ",
				new String[] { document_id }, null);
		cursor.moveToFirst();
		String path = cursor.getString(cursor
				.getColumnIndex(MediaStore.Images.Media.DATA));
		cursor.close();

		return path;
	}

	/**
	 * Gets the corresponding path to a file from the given content:// URI
	 * 
	 * @param uri
	 *            The content:// URI to find the file path from
	 * @param contentResolver
	 *            The content resolver to use to perform the query.
	 * @return the file path as a string
	 */
	public static String getFilePathFromContentUri(Uri uri,
			ContentResolver contentResolver) {
		String filePath = null;
		Uri _uri = uri;
		Log.d("", "URI = " + _uri);
		if (_uri != null && "content".equals(_uri.getScheme())) {
			Cursor cursor = contentResolver
					.query(_uri,
							new String[] { android.provider.MediaStore.Images.ImageColumns.DATA },
							null, null, null);
			cursor.moveToFirst();
			filePath = cursor.getString(0);
			cursor.close();
		} else {
			filePath = _uri.getPath();
		}
		Log.e("", "Chosen path = " + filePath);
		return filePath;
	}

	// Up load with bitmap
	public String uploadFile() {
		if (android.os.Build.VERSION.SDK_INT > 9) {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}

		int bytesRead, bytesAvailable, bufferSize;
		byte[] buffer;
		int maxBufferSize = 1 * 1024 * 1024;

		if (photo == null) {

			return null;

		} else {
			try {

				// open a URL connection to the Servlet
				String fileName = Util.SaveImage(photo, "1");
				FileInputStream fileInputStream = new FileInputStream(fileName);
				// TODO : input file
				String upLoadServerUri = "https://testing.receiptclub.com/api/v2/receipt-images";
				URL url = new URL(upLoadServerUri);

				// Open a HTTP connection to the URL
				conn = (HttpURLConnection) url.openConnection();
				conn.setDoInput(true); // Allow Inputs
				conn.setDoOutput(true); // Allow Outputs
				conn.setUseCaches(false); // Don't use a Cached Copy
				conn.setRequestMethod("POST");
				conn.setRequestProperty("Connection", "Keep-Alive");
				conn.setRequestProperty("ENCTYPE", "multipart/form-data");
				conn.setRequestProperty("Content-Type",
						"multipart/form-data;boundary=" + boundary);
				conn.setRequestProperty("Filedata", fileName);
				conn.setRequestProperty("AUTH_TOKEN", Const.AUTHENKEY);

				dos = new DataOutputStream(conn.getOutputStream());

				dos.writeBytes(twoHyphens + boundary + lineEnd);
				dos.writeBytes("Content-Disposition: form-data; name=\"Filedata\";filename=\""
						+ fileName + "\"" + lineEnd);

				dos.writeBytes(lineEnd);

				// create a buffer of maximum size
				bytesAvailable = fileInputStream.available();

				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				buffer = new byte[bufferSize];

				// read file and write it into form...
				bytesRead = fileInputStream.read(buffer, 0, bufferSize);

				while (bytesRead > 0) {

					dos.write(buffer, 0, bufferSize);
					bytesAvailable = fileInputStream.available();
					bufferSize = Math.min(bytesAvailable, maxBufferSize);
					bytesRead = fileInputStream.read(buffer, 0, bufferSize);

				}

				// send multipart form data necesssary after file data...
				dos.writeBytes(lineEnd);
				dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

				// Responses from the server (code and message)
				serverResponseCode = conn.getResponseCode();
				String serverResponseMessage = conn.getResponseMessage();

				Log.i("uploadFile", "HTTP Response is : "
						+ serverResponseMessage + ": " + serverResponseCode);

				if (serverResponseCode == 200) {

					try {
						in = conn.getInputStream();
						JsonContent = readData(in);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					;
				} else {
					Toast.makeText(
							ct,
							"Currently, this android version is not supported Uploading function!",
							Toast.LENGTH_SHORT).show();
				}

				// close the streams //
				fileInputStream.close();
				dos.flush();
				dos.close();

			} catch (MalformedURLException ex) {

				ex.printStackTrace();

				ct.runOnUiThread(new Runnable() {
					public void run() {

						Toast.makeText(ct, "MalformedURLException",
								Toast.LENGTH_SHORT).show();
					}
				});

				Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
			} catch (Exception e) {

				e.printStackTrace();
				Toast.makeText(ct, e.getMessage(), Toast.LENGTH_SHORT).show();

				Log.e("Upload file to server Exception",
						"Exception : " + e.getMessage(), e);
			}

			return JsonContent;

		} // End else block
	}

	private static String readData(InputStream in) throws IOException {
		if (in == null)
			return null;
		StringBuilder sb = new StringBuilder();
		BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
		for (String line = r.readLine(); line != null; line = r.readLine()) {
			sb.append(line);
		}
		in.close();
		return sb.toString();
	}
}